import { GlobalDefinition } from "./GlobalDefinition";
import { CommonFunction } from "./CommonFunction";
import { EventDefinition } from "./EventDefinition";
/**数据记录类 */
export class DataRecordClass {
    private static self: DataRecordClass;
    /**文件名称标记*/
    public static FileNameTag: string = "arr";

    /**地图映射数组*/
    private MapArr: number[][] = [];
    /**地图JSON对象*/
    private MapJson: {} = {};
    private CMF: CommonFunction;
    /**弹出框主体div*/
    private EjectArea: HTMLDivElement;
    /**点击下载按钮 */
    private DownLoadBtn: HTMLInputElement;
    /**点击复制按钮 */
    private ClickCopyBtn: HTMLInputElement;
    /**文本编辑框*/
    private TextArea: HTMLTextAreaElement;
    /**关闭弹出框按钮 */
    private CloseEject: HTMLButtonElement;
    /**上传的图块容器Div */
    private BlockContent: HTMLDivElement;
    /**图块资源名称数组 */
    private BlockNames: string[] = [];

    public static ins() {
        if (DataRecordClass.self != null) {
            return DataRecordClass.self;
        } else {
            return new DataRecordClass();
        }
    }

    public constructor() {
        this.CMF = CommonFunction.ins();
        DataRecordClass.self = this;
        this.InitView();
        this.InitData();
    }

    /**初始化数据内容*/
    private InitData() {
        this.InitMapArr(GlobalDefinition.BlockHeightSum, GlobalDefinition.BlockWidthSum);
        this.InitMapJson(this.MapJson);
        this.StringOutMaparr();
    }

    /**初始化页面操作*/
    private InitView() {
        this.DownLoadBtn = this.CMF.IdToElement("tex-download") as HTMLInputElement;
        this.ClickCopyBtn = this.CMF.IdToElement("tex-copy") as HTMLInputElement;
        this.TextArea = this.CMF.IdToElement("tex-tea") as HTMLTextAreaElement;
        this.CloseEject = this.CMF.IdToElement("close-eject") as HTMLButtonElement;
        this.EjectArea = this.CMF.IdToElement("eject-area") as HTMLDivElement;
        this.BlockContent = this.CMF.IdToElement("topFunc") as HTMLDivElement;
        this.CMF.ListenerTypeEvents([this.DownLoadBtn, this.ClickCopyBtn, this.CloseEject], EventDefinition.CLICK, this.OnClick.bind(this));

    }

    /**初始化地图映射数组[变为二维数组] 
     * @param row 行
     * @param line 列
    */
    private InitMapArr(row: number, line: number) {
        for (let i = 0; i < row; i++) {
            let temp: number[] = [];
            this.MapArr.push(temp);
            for (let j = 0; j < line; j++) {
                this.MapArr[i].push(0);
            }
        }
    }

    /**初始化地图JSON对象
     * @param initJson 初始化的json对象
    */
    private InitMapJson(initJson: {}) {
        let map_width: number = GlobalDefinition.MainCanvasWidth;  //画布宽
        let map_height: number = GlobalDefinition.MainCanvasHeight;  //画布高
        let block_width: number = GlobalDefinition.BlockWidth;  //图块宽
        let block_height: number = GlobalDefinition.BlockHeight;  //图块高
        let mapW: Map<string, any> = new Map();
        let mapH: Map<string, any> = new Map();
        let mapArr: Map<string, string>[] = [];
        let blockW: Map<string, any> = new Map();
        let blockH: Map<string, any> = new Map();
        blockW.set("block_width", block_width);
        blockH.set("block_height", block_height);
        mapW.set("map_width", map_width);
        mapH.set("map_height", map_height);
        //往空对象里添加属性
        this.CMF.AddObjectAttribute(initJson, [mapW, mapH]);
        this.CMF.AddObjectAttribute(initJson, [blockW, blockH]);
        for (let row = 0; row < this.MapArr.length; row++) {
            let temp: Map<string, string> = new Map();
            temp.set(row + "", "[]");
            mapArr.push(temp);
        }
        this.CMF.AddObjectAttribute(initJson, mapArr);
        // console.log(initJson);
    }

    /**获取读取的图块资源名称 
     * @param blockContent 图块容器
    */
    private GetBlockNames(blockContent: HTMLDivElement) {
        let divChilds: HTMLCollection = blockContent.children;
        for (let i = 0; i < divChilds.length; i++) {
            if (divChilds[i] instanceof HTMLDivElement) {
                //若存在则覆盖
                if (this.BlockNames[i] != null) {
                    this.BlockContent[i] = divChilds[i].id;
                } else {
                    this.BlockNames.push(divChilds[i].id);
                }
            }
        }
        //console.log(this.BlockNames);
    }

    /**将包含一维数组的数据加入文本编辑框
     * @param arrsName 数组名称
     * @param addArrs 一维数据数组
     * @param addContent 要添加内容的编辑框
    */
    private AddOneToContent(arrsName: string, addArrs: string[], addContent: HTMLTextAreaElement) {
        let name: string = "var " + arrsName + " = \n";
        let tempStr: string = "[";
        addContent.value += name;  //添加变量名
        for (let i = 0; i < addArrs.length; i++) {
            if (i + 1 == addArrs.length) {
                tempStr += addArrs[i] + "];";
            } else {
                tempStr += addArrs[i] + ",";
            }
        }
        if (addArrs.length == 0) {
            tempStr = "[ ];"
        }
        addContent.value += tempStr + "\n";
    }

    /**将地图映射数组输出为文字字符串*/
    private StringOutMaparr() {
        let temp_row: string = "[";
        let temp_arr: number[] = [];
        this.TextArea.style.textAlign = "center";
        this.TextArea.value = "var map = [\n";
        for (let row = 0; row < this.MapArr.length; row++) {
            temp_arr = this.MapArr[row];
            for (let line = 0; line < temp_arr.length; line++) {
                if (line + 1 == temp_arr.length) {
                    temp_row += temp_arr[line] + "]";
                } else {
                    temp_row += temp_arr[line] + ",";
                }
            }
            this.TextArea.value += temp_row;
            temp_row = "[";
        }
        this.TextArea.value += "];\n";
    }

    /**将地图JSON数据输出为文字字符串*/
    private StringOutJson() {
        let index: number = 0;  //对象计数
        let count: number = Object.keys(this.MapJson).length;  //获取对象长度
        let temp_row: string = "";
        let temp_obj: string = "{\"map_json\": { \n"
        this.TextArea.value += temp_obj;
        for (let key in this.MapJson) {
            index += 1;
            //判断key是否可以转换为数组索引
            if (isNaN(parseInt(key)) != true) {
                let row: number[] = this.MapArr[parseInt(key)];
                temp_row += "\"" + key + "\": ["
                for (let i = 0; i < row.length; i++) {
                    if (i + 1 == row.length) {
                        temp_row += row[i] + "],";
                    } else {
                        temp_row += row[i] + ",";
                    }
                }
                temp_row += "\n";
                this.TextArea.value += temp_row;
                temp_row = "";
            } else {
                //若到达末尾不加逗号否则json的格式就是错的
                if (index == count) {
                    this.TextArea.value += "\"" + key + "\":\"" + this.MapJson[key] + "\" }}\n";
                } else {
                    this.TextArea.value += "\"" + key + "\":\"" + this.MapJson[key] + "\",\n";
                }
            }
        }
    }

    /**点击监听回调 */
    private OnClick(e) {
        let event = e[0];
        switch (event) {
            case this.ClickCopyBtn:
                let Tips: HTMLLabelElement = this.CMF.IdToElement("tips") as HTMLLabelElement;
                this.TextArea.select();
                document.execCommand("Copy")
                Tips.innerText = "复制成功!";
                break;
            case this.DownLoadBtn:
                let eleLink = document.createElement('a');
                if (DataRecordClass.FileNameTag == "arr") {
                    eleLink.download = "MapArr.js";
                } else if (DataRecordClass.FileNameTag == "json") {
                    eleLink.download = "MapJson.json";
                } else {
                    eleLink.download = "DataString.txt";
                }
                eleLink.style.display = 'none';
                // 字符内容转变成blob地址
                let blob = new Blob([this.TextArea.value]);
                eleLink.href = URL.createObjectURL(blob);
                // 触发点击
                document.body.appendChild(eleLink);
                eleLink.click();
                // 然后移除
                document.body.removeChild(eleLink);
                break;
            case this.CloseEject:
                this.EjectArea.style.display = "none";
                break;
        }
    }

    /**往地图数组添加图块序号标记
     * @param curr_row 当前行
     * @param curr_line 当前列
     * @param tag 当前图块标记值
    */
    public AddArrTag(curr_row: number, curr_line: number, tag: number) {
        if (curr_row < GlobalDefinition.BlockHeightSum) {
            if (curr_line < GlobalDefinition.BlockWidthSum) {
                this.MapArr[curr_row][curr_line] = tag;
                //console.log(this.MapArr)
            }
        }
    }

    /**地图数组与JSON数据重置 */
    public MapDataReset() {
        //清空地图数组
        for (let row = 0; row < this.MapArr.length; row++) {
            this.MapArr[row].splice(0, this.MapArr[row].length);
        }
        this.MapArr.splice(0, this.MapArr.length);
        //重新初始化地图数组
        this.InitMapArr(GlobalDefinition.BlockHeightSum, GlobalDefinition.BlockWidthSum);
        this.MapJson = {};  //重新初始化地图json
        this.InitMapJson(this.MapJson);
    }

    /**地图数组显示刷新 */
    public MapArrUpdate() {
        this.TextArea.value = "";
        this.StringOutMaparr();
        this.GetBlockNames(this.BlockContent);
        this.AddOneToContent("blockwidth", [GlobalDefinition.BlockWidth + ""], this.TextArea);
        this.AddOneToContent("blockheight", [GlobalDefinition.BlockHeight + ""], this.TextArea);
        this.AddOneToContent("blocknames", this.BlockNames, this.TextArea);
        this.TextArea.value += "//Tips: (map)地图数组中的序号对应图块名称数组(blocknames)中的顺序!\n"
    }

    /**地图JSON显示刷新 */
    public MapJsonUpdate() {
        this.TextArea.value = "";
        this.StringOutJson();
    }
}